#include "IceLinkPool.h"

namespace cm_nat
{
    IceLinkPool::IceLinkPool()
    {

    }

    IceLinkPool::~IceLinkPool()
    {

    }

    int IceLinkPool::setHostIP(IPAddress host_ip)
    {
        m_hostIP = host_ip;

        return CM_RES_SUCCESS;
    }

    int IceLinkPool::setup( UInt16 poolSize, SocketAddress stunAddress )
    {
        m_stunAddress = stunAddress;

        m_reactor.setTimeout( Poco::Timespan(1,0,0,0,0) );

        m_bufferPool.setup(20,1024);

        m_reactorThread.start( m_reactor );

        m_timer.setup();

        for( int i=0;i<poolSize; i++ ){

            IceLink* p_link = new IceLink(this, &m_bufferPool, &m_reactor, &m_timer );
            m_links.push_back( p_link );

            p_link->setStunAddress( m_stunAddress );

            p_link->setup( m_hostIP );
        }

        return CM_RES_SUCCESS;
    }

    int IceLinkPool::teardown()
    {
        return CM_RES_SUCCESS;
    }

    IceLink* IceLinkPool::allocateLink()
    {
        IceLink* p_link = NULL;

        IceLinkList::iterator it = m_readyLinks.begin();
        if( it!=m_readyLinks.end() ){
            p_link = *it;
            m_readyLinks.erase(it);
        }

        return p_link;
    }

    int IceLinkPool::releaseLink( IceLink* p_link )
    {
        p_link->reset();

        return CM_RES_SUCCESS;
    }

    int IceLinkPool::startCheckConnection( IceLink* link, SocketAddress peer )
    {
        link->checkConnection( peer );

        return CM_RES_SUCCESS;
    }

    void IceLinkPool::onCheckResult( IceLink* link, int result )
    {
        switch(result)
        {
        case IceLink::CHECK_RES_STUN_CHECK_SUCCESS:
            {
                m_readyLinks.push_back( link );
                poco_debug( g_log_nat, Logger::format("stun reflex address:$0", link->getStunReflexAddress().toString() ) );
            }
            break;

        case  IceLink::CHECK_RES_PEER_CHECK_SUCCESS:
            {
                IceLinkListener* p_listener = link->m_listener;
                if( p_listener ){
                    p_listener->onLinkState( link, IceLink::STATE_KEEP_PEER_CHECK );
                }
                poco_debug(g_log_nat, "IceLink::CHECK_RES_PEER_CHECK_SUCCESS\n");
                poco_debug( g_log_nat, Logger::format("peer reflex address:$0", link->getPeerReflexAddress().toString() ) );
            }
            break;

        case IceLink::CHECK_RES_STUN_CHECK_FAIL:
            {

            }
            break;

        case IceLink::CHECK_RES_PEER_CHECK_FAIL:
            {
                IceLinkListener* p_listener = link->m_listener;
                if( p_listener ){
                    p_listener->onLinkState( link, IceLink::STATE_KEEP_PEER_CHECK_FAIL );
                }
                poco_debug(g_log_nat, "IceLink::STATE_KEEP_PEER_CHECK_FAIL");

            }
            break;

        default:
            break;

        }

    }


}